/**
 * @author mmbro
 * @homepage https://gitee.com/mmbro/
 * @date 2021年05月18日02:26:30
 * @description 注释:断言工具类(非项目代码,禁止使用本工具类,让其他工具类尽量脱钩,工具类最少依赖原则)
 */
AssertUtil = class AssertUtil {
    /**
     * @description 断言对象,保存断言工具类私有方法
     * @type {AssertUtil}
     */
    static assert = new AssertUtil();

    /**
     * @description 断言自定义异常
     * @type {*}
     * @link https://blog.csdn.net/zhang197093/article/details/52055850
     */
    AssertException = class AssertException {
        message;

        constructor(message) {
            this.message = message;
        }
    };

    /**
     * @description 断言不为空
     * @param objs
     */
    static assertNull(...objs) {
        for (let i = 0; i < objs.length; i++) {
            const obj = objs[i];
            if (AssertUtil.assert.isNull(obj)) {
                let posStr = AssertUtil.assert.getErrorPos(objs, i);
                throw new AssertUtil.assert.error('null Point exception!' + posStr);
            }
        }
    }

    /**
     * @description 断言不为空,且元素数量不为0
     * @param objs
     */
    static assertBlank(...objs) {
        for (let i = 0; i < objs.length; i++) {
            const obj = objs[i];
            if (AssertUtil.assert.isBlank(obj)) {
                let posStr = AssertUtil.assert.getErrorPos(objs, i);
                throw new AssertUtil.assert.error('blank exception!' + posStr);
            }
        }
    }

    /**
     * @description 对象不为空
     * @param obj
     * @returns {boolean}
     */
    isNull(obj) {
        return obj === null || typeof obj === 'undefined';
    }

    /**
     * @description 对象不为空,且元素数量等于0
     * @param obj
     * @returns {boolean}
     */
    isBlank(obj) {
        return this.isNull(obj) || Object.keys(obj).length === 0;
    }

    /**
     * @description 获取断言失败下标
     * @param objs 断言参数对象数组
     * @param i 失败下标
     * @returns {string|string} 断言位置字符串
     */
    getErrorPos(objs, i) {
        return objs.length > 1 ? ' pos:' + (i + 1) + ' asserts:[' + objs + ']' : '';
    }

    /**
     * @description 构造断言失败异常对象
     * @param msg 断言失败信息
     * @returns {AssertException}
     */
    error(msg) {
        return new this.AssertException(msg);
    }
}